package com.ecloud.common.base.result;

import java.beans.Transient;
import java.io.Serializable;
import java.util.Locale;

/**
 * 统一结果级封装
 *
 * @author LiuGangQiang Create in 2021/04/02
 */
public final class Result<T> implements Serializable {

    private static final long serialVersionUID = 1167667866208913058L;

    /**
     * 默认资源文件路径
     *
     * @author LiuGangQiang Create in 2020/04/02
     */
    private static final String DEFAULT_PATH = "i18n.core";

    /**
     * 响应状态码 请参考 {@link ResultStatus}
     *
     * @author LiuGangQiang Create in 2021/04/02
     */
    private Integer code;
    /**
     * 响应数据
     *
     * @author LiuGangQiang Create in 2021/04/02
     */
    private T data;
    /**
     * 响应描述信息
     *
     * @author LiuGangQiang Create in 2021/04/02
     */
    private String msg;

    /**
     * 语言环境 不序列化
     *
     * @author LiuGangQiang Create in 2021/04/02
     */
    private Locale locale;
    /**
     * 响应描述信息对应在资源文件的路径 不序列化
     *
     * @author LiuGangQiang Create in 2021/04/02
     */
    private String path;

    /**
     * 响应描述信息对应在资源文件中的键值 不序列化
     *
     * @author LiuGangQiang Create in 2021/04/02
     */
    private String key;

    /**
     * 响应描述信息参数
     *
     * @author LiuGangQiang Create in 2021/04/02
     */
    private Object[] args;

    /**
     * 空构造器
     *
     * @author LiuGangQiang Create in 2021/08/11
     */
    public Result() {
    }

    /**
     * 构造器 设为私有对外不提供
     *
     * @author LiuGangQiang Create in 2021/04/02
     * @param code 状态码
     * @param data 数据
     * @param msg  消息
     * @param key  资源键值
     */
    protected Result(Integer code, T data, String msg, String key) {
        this.code = code;
        this.data = data;
        this.msg = msg;
        this.key = key;
    }

    /**
     * @param code the code to set
     */
    public void setCode(Integer code) {
        this.code = code;
    }

    /**
     * @param msg the msg to set
     * @return {@link Result}
     */
    public Result<T> setMsg(String msg) {
        this.msg = msg;
        return this;
    }

    /**
     * @param locale the locale to set
     * @return {@link Result}
     */
    public Result<T> setLocale(Locale locale) {
        this.locale = locale;
        return this;
    }

    /**
     * @param path the path to set
     * @return {@link Result}
     */
    public Result<T> setPath(String path) {
        this.path = path;
        return this;
    }

    /**
     * @param key the key to set
     * @return {@link Result}
     */
    public Result<T> setKey(String key) {
        this.key = key;
        /* 这里手动设置了资源键值如果没设置资源路径就需要设置资源路径 */
        if (isBlank(this.path)) {
            this.path = Prompt.getFilepath();
        }
        return this;
    }

    /**
     * @param key  the key to set
     * @param args the args to set
     * @return {@link ResultApi}
     */
    public Result<T> setKey(String key, Object... args) {
        this.args = args;
        this.key = key;
        /* 这里手动设置了资源键值如果没设置资源路径就需要设置资源路径 */
        if (isBlank(this.path)) {
            this.path = Prompt.getFilepath();
        }
        return this;
    }

    /**
     * @param args the args to set
     */
    public void setArgs(Object[] args) {
        this.args = args;
    }

    /**
     * @return the code
     */
    public Integer getCode() {
        return code;
    }

    /**
     * @return the data
     */
    public T getData() {
        return data;
    }

    /**
     * @return the msg
     */
    public String getMsg() {
        if (this.msg != null) {
            /* 消息优先级最高不为空直接返回 */
            return msg;
        }
        if (this.key == null) {
            /* 如果资源键值为空则直接返回空 */
            return null;
        }
        /* 否则证明需要通过资源文件获取 */
        if (this.path == null) {
            /* 没有设置资源路径直接使用默认路径 */
            return Prompt.bundle(DEFAULT_PATH, getLocale(), this.key);
        } else {
            /* 设置了资源路径则采用设置的路径 */
            return Prompt.bundle(this.path, getLocale(), this.key, this.args);
        }
    }

    /**
     * @return the locale
     */
    @Transient
    public Locale getLocale() {
        return locale == null ? Locale.getDefault() : locale;
    }

    /**
     * @return the key
     */
    @Transient
    public String getKey() {
        return key;
    }

    /**
     * 比较两个状态码是否一致
     *
     * @author LiuGangQiang Create in 2021/04/02
     * @param status 状态枚举
     * @return 是否一致
     */
    public boolean compare(ResultStatus status) {
        return status.getValue().equals(this.code);
    }

    /**
     * 判断是否是空字符串
     *
     * @author LiuGangQiang Create in 2021/09/07
     * @param str 字符串
     * @return {@link Boolean}
     */
    private boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public String toString() {
        return "[code=" + code + ", data=" + data + ", msg=" + getMsg() + "]";
    }
}
